package es.decoroso.fakeAgent;

import java.util.LinkedList;
import java.util.List;

import es.decoroso.communicationAgent.bean.Message;
import es.decoroso.communicationAgent.bean.Rower;
import es.decoroso.communicationAgent.bean.Vector2;
import es.decoroso.fakeAgent.behaviours.NotifyGraphicLayer;
import jade.core.AID;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;

/**
 * Represents a boat
 * 
 * Only for testing.
 * You have to merge this code with your actual Boat code.
 * 
 * @author Jesús W. Jiménez
 *
 */
public class Boat extends Agent {
	
	////////////////////////////////////////////////
	////  ADD ALL THIS PARAMS 					////
	////////////////////////////////////////////////
	/** Actual position of the boat */
	Vector2 position = new Vector2(0f, 0f);
	
	/** Actual orientation of the boat */
	Vector2 orientation = new Vector2(0f, 0f);
	
	/** Group number */ // Put your group number here
	int groupNumber = 0;
	
	/** Rowers of the boat */ // You have to update this variable
	List<Rower> rowers = new LinkedList<Rower>();

	// Params used to calculate the row 
	float timer = 3000f;
	float posX, posY;
	float rowX, rowY;

	/** Id of the communication agent */
	private AID comunicationAgent;

	/**
	 * On the setup method we should find the COMMUNICATION agent, and add the
	 * new behaviour.
	 * 
	 * You have to merge this setup with yours
	 */
	@Override
	protected void setup() {
		super.setup();
	
		doWait(2000); // Wait for the communication service to be ready
		
		// SET THE START POSITION
		setStartPosition();

		// FIND THE COMMUNICATION AGENT
		this.comunicationAgent = locateService(this, "COMMUNICATION"); // ADD THIS  LINE

		// ADD THE BEHAVIOUR
		//addBehaviour(new NotifyGraphicLayer(this, comunicationAgent)); // ADD THIS LINE
	}

	
	
	///////////////////////////////////////////////////////
	// ADD THE CODE FROM HERE TO THE END OF THE DOCUMENT //
	///////////////////////////////////////////////////////
	/**
	 * Call this method after set the group number
	 * 
	 * This methods sets the start position of the boat
	 */
	private void setStartPosition() {
		position.x = groupNumber*25;

	}
	/**
	 * Start a row
	 * 
	 * This method should be called when a new row it's been received.
	 * 
	 * @param x X Value of the row
	 * @param y Y Value of the row
	 */
	public void toRow(float x, float y) {
		posX = position.x;
		posY = position.y;

		if (timer < 3000) { // row not finished
			float restX =  orientation.x - orientation.x * timer / 3000.0f;
			float restY =  orientation.y - orientation.y * timer / 3000.0f;

			orientation.x = restX + x;
			orientation.y = restY + y;
		} else {
			orientation.x = x;
			orientation.y = y;
		}

		timer = 0;
	}

	
	/**
	 * Update the position of the boat
	 */
	private void updateRow() {
		if (timer <= 3000) {
			position.x = posX + (orientation.x * timer / 3000.0f);
			position.y = posY + (orientation.y * timer / 3000.0f);
		}
	}

	/**
	 * This method is called from NotifyGraphicLayer
	 * 
	 * This method updates the row force and send the information
	 * to the graphic layer
	 * 
	 * @return Message with the actual position of the system
	 */
	public Message createMessage() {
		timer = timer + 50;
		updateRow();
		Message m = new Message(groupNumber, orientation, position, rowers);
		return m;
	}

	/**
	 * This method search for an agent that offers a service we are searching
	 * for
	 * 
	 * @param agentType Type of agent you want to locate
	 * 
	 * @return AID of identifyed agent or null if not found
	 */
	private AID locateService(Agent agent, String agentType) {

		AID result = null;

		// Create agent description
		DFAgentDescription dfd = new DFAgentDescription();
		ServiceDescription sd = new ServiceDescription();
		sd.setType(agentType);
		dfd.addServices(sd);

		// Search requested type agents
		DFAgentDescription[] res = new DFAgentDescription[1];
		try {
			res = DFService.search(agent, dfd);
			if (res.length > 0) {
				result = res[0].getName();
			} else {
				// Not agent found
				return null;
			}
		} catch (FIPAException ex) {
			// Not agent found exception
			ex.printStackTrace();
		}
		return result;
	}
}
